import json
import logging
import os
import sys
import time

import requests
from flask import Blueprint

from app.modules1.PublicApproach import get_token_result
from app.modules1.common.encryptionUtils import getResult1

# 设置标准输出编码为UTF-8，确保中文正确显示
if sys.stdout.encoding != 'utf-8':
    sys.stdout.reconfigure(encoding='utf-8')

# 创建蓝图
vendinfo_bp = Blueprint('erp-purch', __name__)

# 确保日志目录存在
log_dir = "logs"
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

# 使用标准日志配置
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("logs/purch_data_sync.log", encoding='utf-8'),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

# 数据库连接函数
from config import DB


def save_purch_data_to_db(purch_data):
    """
    将采购数据保存到数据库c_purch_data表中
    实现增量更新逻辑：
    1. 对比获取的数据和数据库中原有数据
    2. 如果orderNum相同则视为同一条数据，不执行插入
    3. 如果获取的数据中没有现有数据，则删除数据库中的这条数据
    4. 如果是新数据则插入
    :param purch_data: 采购数据列表
    """
    connection = None
    try:
        # 获取数据库连接
        connection = DB()
        cursor = connection.cursor()

        # 获取数据库中现有的所有orderNum
        cursor.execute("SELECT order_num FROM c_purch_data")
        existing_orders = set(row[0] for row in cursor.fetchall())

        # 获取当前获取到的所有orderNum
        current_orders = set(item.get('orderNum') for item in purch_data)

        # 找出需要删除的数据（在数据库中存在，但这次获取的数据中没有）
        orders_to_delete = existing_orders - current_orders
        if orders_to_delete:
            delete_sql = "DELETE FROM c_purch_data WHERE order_num IN ({})".format(
                ','.join(['%s'] * len(orders_to_delete))
            )
            cursor.execute(delete_sql, list(orders_to_delete))
            logger.info(f"删除了 {len(orders_to_delete)} 条旧数据")

        # 找出需要插入的数据（这次获取到的，但数据库中没有的）
        orders_to_insert = current_orders - existing_orders
        data_to_insert = []
        for item in purch_data:
            if item.get('orderNum') in orders_to_insert:
                data_to_insert.append((
                    item.get('crtName') or "木兰姐",  # 确保即使为空也使用默认值
                    item.get('provCreate'),  # 已经是格式化后的日期字符串
                    item.get('orderNum'),
                    item.get('goodsName'),
                    item.get('quantity'),
                    item.get('amount')
                ))

        # 插入新数据
        if data_to_insert:
            insert_sql = """
            INSERT INTO c_purch_data 
            (crtName, prov_create, order_num, goods_name, quantity, amount) 
            VALUES (%s, %s, %s, %s, %s, %s)
            """
            cursor.executemany(insert_sql, data_to_insert)
            logger.info(f"插入了 {len(data_to_insert)} 条新数据")

        connection.commit()
        logger.info(f"数据同步完成：删除 {len(orders_to_delete)} 条，新增 {len(data_to_insert)} 条")

    except Exception as e:
        if connection:
            connection.rollback()
        logger.error(f"保存采购数据到数据库时出错: {e}")
    finally:
        if connection:
            connection.close()


def get_Purch_data():
    """
    分页获取采购数据，直到某页数据不足pageSize条数
    """
    all_data = []  # 存储所有获取到的数据
    page_size = 200  # 每页数据量
    page_index = 0  # 当前页码，从0开始

    while True:
        token = get_token_result()
        # logger.info(f'获取到token: {token}')
        url = "https://env3.jkyservice.com/jkyun/erp-purch/order/listgoods"
        headers = {
            "authority": "env3.jkyservice.com",
            "method": "POST",
            "path": "/jkyun/erp-purch/order/listgoods",
            "scheme": "https",
            "accept": "*/*",
            "accept-encoding": "gzip, deflate, br, zstd",
            "accept-language": "zh-CN,zh;q=0.9",
            "module_code": "supplier_list_new_list",
            "origin": "https://env3.jkyservice.com",
            "priority": "u=1, i",
        }

        data = {
            "revwStatus": 2,
            "payStatus": "5,9",
            "isExpired": 2,
            "orderType": 1,
            "isPackageSon": 0,
            "purchSearchGoodsType": 1,
            "pageIndex": page_index,
            "pageSize": page_size,
            "cols": ["busiName", "orderNum", "crtName", "purchType", "orderTime", "provDate", "gmtCreate", "vendName",
                     "revwStatus", "inApplyStatus", "inStatus", "settStatus", "warehouseName", "freezeReason",
                     "goodsNo", "goodsName", "skuProperitesName", "skuBarcode", "unitName", "quantity", "price",
                     "taxPrice", "noTaxAmount", "amount", "applyQuantity", "inQuantity", "inAmount", "settPrice",
                     "settQuantity", "lineClose", "goodsField18", "goodsField20", "expectArrivalDate", "goodsField6",
                     "goodsField17", "goodsField21", "goodsField30", "skuField5", "isReturnFlag", "id", "orderId",
                     "flagData", "text", "billSource", "source", "remindMsg", "warehouseId", "vendId", "skuId",
                     "goodsId", "isPackageInfo", "isSerialManagement", "goodsAttr", "logisticNo", "logisticName",
                     "receivePhone", "vendOrderId", "isAssemblyManagement", "isFreeze", "purchCode", "isBatch",
                     "isSource1688"]
        }
        logger.info(f'构造的数据: {data}')
        requests_data = getResult1(token, data)
        r = requests.post(url, headers=headers, data=requests_data)

        # 解析响应数据
        response_data = r.json()
        if response_data.get('code') == 200 and 'result' in response_data and 'data' in response_data['result']:
            page_data = response_data['result']['data']
            print(json.dumps(page_data, indent=4, ensure_ascii=False))
            # 添加当前页数据到总数据中
            all_data.extend(page_data)

            # 如果当前页数据少于pageSize，说明已经是最后一页，跳出循环
            if len(page_data) < page_size:
                logger.info(f"获取完成，第{page_index}页数据少于{page_size}条，总共获取到{len(all_data)}条数据")
                break
            else:
                # 写入日志
                logger.info(f"已获取第{page_index}页数据，当前共{len(all_data)}条")
                page_index += 1  # 继续下一页
        else:
            logger.error(f"API请求失败: {response_data}")
            break

    return all_data


# 提取数据
def extract_purch_data():
    """提取采购数据并返回"""
    data = get_Purch_data()
    if data is None:
        return []
    # 提取需要的字段
    extracted_data = []
    for item in data:
        extracted_item = {
            # 如果crtName为空则使用默认值
            "crtName": item.get('crtName') or '木兰姐',
            # provCreate 需要去掉后三位，并进行时间戳转换
            "provCreate": time.strftime('%Y-%m-%d', time.localtime(item.get('provCreate') / 1000)) if item.get(
                'provCreate') else None,
            'orderNum': item.get('orderNum'),  # 采购单号
            'goodsName': item.get('goodsName'),  # 商品名称
            'quantity': item.get('quantity'),  # 数量
            'amount': item.get('amount'),  # 金额

        }
        extracted_data.append(extracted_item)

    logger.info(f"数据提取完成，共提取到 {len(extracted_data)} 条数据")
    return extracted_data


def AutoGet_data():
    # 获取提取后的数据
    logger.info("开始获取采购数据")
    purch_data = extract_purch_data()
    logger.info(f"获取到 {len(purch_data)} 条采购数据，准备保存到数据库")

    # 保存到数据库
    save_purch_data_to_db(purch_data)
    logger.info("采购数据保存完成")


if __name__ == '__main__':
    AutoGet_data()
